unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, TunnelThrd, ExtCtrls, ComCtrls, ImgList, synautil, Grids,
  JvExGrids, JvGrids, JvExStdCtrls, JvHtControls, Menus, JvMenus,
  JvComponentBase, JvClipboardMonitor, JvTrayIcon;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    ImageList1: TImageList;
    list: TJvHTListBox;
    JvPopupMenu1: TJvPopupMenu;
    JvXPMenuItemPainter1: TJvXPMenuItemPainter;
    mNew: TMenuItem;
    mEdit: TMenuItem;
    mDelete: TMenuItem;
    N1: TMenuItem;
    mStart: TMenuItem;
    tray: TJvTrayIcon;
    JvPopupMenu2: TJvPopupMenu;
    ShowHide1: TMenuItem;
    Quit1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure listClick(Sender: TObject);
    procedure mNewClick(Sender: TObject);
    procedure mEditClick(Sender: TObject);
    procedure listDblClick(Sender: TObject);
    procedure mDeleteClick(Sender: TObject);
    procedure mStartClick(Sender: TObject);
    procedure ShowHide1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Quit1Click(Sender: TObject);
  private
    { Private declarations }
  public
    arq: string;
    procedure save(filename: string);
    procedure load(filename: string);
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  arq := ParamStr(1);
  if FileExists(arq) then
    Load(arq);
  timer1.enabled := true;
  tray.Active := True;
  tray.HideApplication;
  //WindowState := wsMinimized
end;

procedure TForm1.load(filename: string);
var
  F: Textfile;
  s: string;
  P: PTunnelItem;
begin
  assignfile(f, filename);
  reset(f);
  while not eof(f) do
  begin
    readln(f, s);
    new(P);
    P.name := FetchBin(s, ',');
    P.lport := FetchBin(s, ',');
    P.dhost := FetchBin(s, ',');
    P.dport := FetchBin(s, ',');
    P.password := FetchBin(s, ',');
    if FetchBin(s, ',') = 'started' then
      TTunnelThread.Create(P)
    else
      P.Thread := nil;
    list.items.AddObject('<b>'+p.name+',</b> Loaded', TObject(P));
  end;
  closefile(f);
end;

procedure TForm1.save(filename: string);
var
  I: Integer;
  f: textfile;
  P: PTunnelItem;
begin
  assignfile(f, filename);
  rewrite(f);
  for I := 0 to list.items.count - 1 do
  begin
    P := PTunnelItem(list.items.objects[I]);
    write(f, P.name+','+P.lport+','+P.dhost+','+P.dport+','+P.password);
    if P.Thread = nil then
      writeln(f,',stopped')
    else
      writeln(f,',started');
  end;
  closefile(f);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  I: Integer;
  P: PTunnelItem;
  s: String;
begin
  list.items.BeginUpdate;
  try
    for I := 0 to list.items.count - 1 do
    begin
      P := PTunnelItem(list.items.objects[I]);
      if P.Thread = nil then
        s := 'Stopped'
      else
        case P.Thread.state of
          tsBinding:
            s := 'Binding';
          tsBindFail:
            s := 'Bind fail';
          tsListenning:
            s := 'Listenning';
          tsConnected:
            s := 'Connected';
        end;
      list.items[I] := '<b>'+P.name+',</b>  '+s;
    end;
  finally
    list.items.EndUpdate;
  end;
end;

procedure TForm1.listClick(Sender: TObject);
begin
  mNew.Enabled := true;
  mEdit.Enabled := list.ItemIndex > -1;
  mDelete.Enabled := list.ItemIndex > -1;
  mStart.Enabled := list.ItemIndex > -1;
end;

procedure TForm1.mNewClick(Sender: TObject);
var
  Form2: TForm2;
  P: PTunnelItem;
begin
  Form2 := TForm2.Create(nil);
  try
    Form2.edStart.visible := true;
    if Form2.ShowModal = mrOk then
    begin
      new(P);
      P.Thread := nil;
      Form2.save(P);
      P.Thread := nil;
      list.items.AddObject('<b>'+name+',</b> New', TObject(P));
      if Form2.edStart.checked then
        TTunnelThread.Create(P);
      save(arq);
    end;
  finally
    Form2.free;
  end;
end;

procedure TForm1.mEditClick(Sender: TObject);
var
  Form2: TForm2;
  P: PTunnelItem;
  I: Integer;
begin
  I := list.itemindex;
  if I = -1 then
    exit;
  Form2 := TForm2.Create(nil);
  try
    P := PTunnelItem(list.items.objects[I]);
    Form2.load(P);
    if Form2.ShowModal = mrOk then
    begin
      Form2.save(P);
      list.items[i] := '<b>'+name+',</b> New';
      save(arq);
    end;
  finally
    Form2.free;
  end;
end;

procedure TForm1.listDblClick(Sender: TObject);
begin
  mEditClick(nil);
end;

procedure TForm1.mDeleteClick(Sender: TObject);
var
  P: PTunnelItem;
  I: Integer;
begin
  I := list.itemindex;
  if I = -1 then
    exit;
  P := PTunnelItem(list.items.objects[I]);
  if MessageDlg('Confirm deletion: '+P.name, mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin
    if P.Thread <> nil then
      P.Thread.Terminate;
    dispose(P);
    list.items.delete(i);
  end;
end;

procedure TForm1.mStartClick(Sender: TObject);
var
  P: PTunnelItem;
  I: Integer;
begin
  I := list.itemindex;
  if I = -1 then
    exit;
  P := PTunnelItem(list.items.objects[I]);
  if P.Thread = nil then
    TTunnelThread.Create(P)
  else
    P.Thread.Terminate;
end;

procedure TForm1.ShowHide1Click(Sender: TObject);
begin
  tray.ApplicationVisible := not tray.ApplicationVisible;
                                                         {
  if WindowState = wsNormal then
    WindowState := wsMinimized
  else
    WindowState := wsNormal;                              }
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  tray.HideApplication;
  Action := caNone;
end;

procedure TForm1.Quit1Click(Sender: TObject);
begin
  Application.Terminate;
end;

end.
